package com.szh.htmltopdf.controller;


import com.szh.common.resp.Resp;
import com.szh.htmltopdf.service.YearService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/redisson")
@Slf4j
public class RedissonTestController {
    @Resource
    RedissonClient redissonClient;

    @Resource
    private YearService yearService;
    /**
     * RLock 可以实现，分布式下多线程资源竞争下，线程同步化
     *
     * @return
     * @throws InterruptedException
     */
    @GetMapping("/RLock")
    public Resp<String> testRLock() throws InterruptedException {
        // 获得一个锁
        RLock lock = redissonClient.getLock("testRLock");
        try {
            lock.lock();
            otherMethod();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        
        return Resp.ok("ok");
    }


    /**
     * 测试看门狗锁过期时间自动续期
     *
     * @return
     * @throws InterruptedException
     */
    @GetMapping("/testWatchDog")
    public Resp<String> testWatchDog() throws InterruptedException {
        // 获得一个锁
        RLock lock = redissonClient.getLock("testRLock");
        boolean rep = lock.tryLock();
        if (rep) {
            try {
                Thread.sleep(60_000);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
        return Resp.ok("ok");
    }

    public void otherMethod() {
        log.error("执行业务逻辑");
    }


    /** 测试事务和锁
     * @param userId 
     * @return
     */
    @GetMapping("/testTran")
    public String testTran(@RequestParam Long userId){
        RLock lock = redissonClient.getLock("testTran:" + userId);
        lock.lock();
        try {
            yearService.dbWrite(userId);
        } finally {
            lock.unlock();
        }
        return userId+"";
    }

    @GetMapping("/testTran")
    public String testTran2(@RequestParam Long userId){
            dbWrite(userId);
        
        return userId+"";
    }

    @Transactional(rollbackFor = Exception.class)
    public void dbWrite(Long userId) {
        
    }

}
